home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / g / gnu_c / libs-020.zoo / math-68881.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  9.1 KB  |  523 lines

  1. #ifndef _MATH_68881_H
  2. #define _MATH_68881_H
  3.  
  4. /******************************************************************\
  5. *                                   *
  6. *  <math-68881.h>        last modified: 23 May 1992.       *
  7. *                                   *
  8. *  Copyright (C) 1989 by Matthew Self.                   *
  9. *  You may freely distribute verbatim copies of this software       *
  10. *  provided that this copyright notice is retained in all copies.  *
  11. *  You may distribute modifications to this software under the     *
  12. *  conditions above if you also clearly note such modifications    *
  13. *  with their author and date.                               *
  14. *                                   *
  15. *  Note:  errno is not set to EDOM when domain errors occur for    *
  16. *  most of these functions.  Rather, it is assumed that the       *
  17. *  68881's OPERR exception will be enabled and handled           *
  18. *  appropriately by the    operating system.  Similarly, overflow       *
  19. *  and underflow do not set errno to ERANGE.               *
  20. *                                   *
  21. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).           *
  22. *                                   *
  23. \******************************************************************/
  24.  
  25. /* If you find this in GCC,
  26.    please send bug reports to bug-gcc@prep.ai.mit.edu.  */
  27.  
  28. /* Changed by Richard Stallman: % inserted before a #.
  29.    New function `hypot' added.
  30.    Nans written in hex to avoid 0rnan.
  31.    May 1992, use %! for fpcr register.  Break lines before function names.
  32.    December 1989, add parens around `&' in pow.
  33.    November 1990, added alternate definition of HUGE_VAL for Sun.  */
  34.  
  35. #include <errno.h>
  36.  
  37. #ifndef HUGE_VAL
  38. #ifdef __sun__
  39. /* The Sun assembler fails to handle the hex constant in the usual defn.  */
  40. #define HUGE_VAL                            \
  41. ({                                    \
  42.   static union { int i[2]; double d; } u = { {0x7ff00000, 0} };        \
  43.   u.d;                                    \
  44. })
  45. #else
  46. #define HUGE_VAL                            \
  47. ({                                    \
  48.   double huge_val;                            \
  49.                                     \
  50.   __asm ("fmove%.d %#0x7ff0000000000000,%0"    /* Infinity */        \
  51.      : "=f" (huge_val)                        \
  52.      : /* no inputs */);                        \
  53.   huge_val;                                \
  54. })
  55. #endif
  56. #endif
  57.  
  58. __inline static const double
  59. sin (double x)
  60. {
  61.   double value;
  62.  
  63.   __asm ("fsin%.x %1,%0"
  64.      : "=f" (value)
  65.      : "f" (x));
  66.   return value;
  67. }
  68.  
  69. __inline static const double
  70. cos (double x)
  71. {
  72.   double value;
  73.  
  74.   __asm ("fcos%.x %1,%0"
  75.      : "=f" (value)
  76.      : "f" (x));
  77.   return value;
  78. }
  79.  
  80. __inline static const double
  81. tan (double x)
  82. {
  83.   double value;
  84.  
  85.   __asm ("ftan%.x %1,%0"
  86.      : "=f" (value)
  87.      : "f" (x));
  88.   return value;
  89. }
  90.  
  91. __inline static const double
  92. asin (double x)
  93. {
  94.   double value;
  95.  
  96.   __asm ("fasin%.x %1,%0"
  97.      : "=f" (value)
  98.      : "f" (x));
  99.   return value;
  100. }
  101.  
  102. __inline static const double
  103. acos (double x)
  104. {
  105.   double value;
  106.  
  107.   __asm ("facos%.x %1,%0"
  108.      : "=f" (value)
  109.      : "f" (x));
  110.   return value;
  111. }
  112.  
  113. __inline static const double
  114. atan (double x)
  115. {
  116.   double value;
  117.  
  118.   __asm ("fatan%.x %1,%0"
  119.      : "=f" (value)
  120.      : "f" (x));
  121.   return value;
  122. }
  123.  
  124. __inline static const double
  125. atan2 (double y, double x)
  126. {
  127.   double pi, pi_over_2;
  128.  
  129.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  130.      : "=f" (pi)
  131.      : /* no inputs */ );
  132.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  133.      : "=f" (pi_over_2)
  134.      : "0" (pi));
  135.   if (x > 0)
  136.     {
  137.       if (y > 0)
  138.     {
  139.       if (x > y)
  140.         return atan (y / x);
  141.       else
  142.         return pi_over_2 - atan (x / y);
  143.     }
  144.       else
  145.     {
  146.       if (x > -y)
  147.         return atan (y / x);
  148.       else
  149.         return - pi_over_2 - atan (x / y);
  150.     }
  151.     }
  152.   else
  153.     {
  154.       if (y > 0)
  155.     {
  156.       if (-x > y)
  157.         return pi + atan (y / x);
  158.       else
  159.         return pi_over_2 - atan (x / y);
  160.     }
  161.       else
  162.     {
  163.       if (-x > -y)
  164.         return - pi + atan (y / x);
  165.       else if (y < 0)
  166.         return - pi_over_2 - atan (x / y);
  167.       else
  168.         {
  169.           double value;
  170.  
  171.           errno = EDOM;
  172.           __asm ("fmove%.d %#0x7fffffffffffffff,%0"     /* quiet NaN */
  173.              : "=f" (value)
  174.              : /* no inputs */);
  175.           return value;
  176.         }
  177.     }
  178.     }
  179. }
  180.  
  181. __inline static const double
  182. sinh (double x)
  183. {
  184.   double value;
  185.  
  186.   __asm ("fsinh%.x %1,%0"
  187.      : "=f" (value)
  188.      : "f" (x));
  189.   return value;
  190. }
  191.  
  192. __inline static const double
  193. cosh (double x)
  194. {
  195.   double value;
  196.  
  197.   __asm ("fcosh%.x %1,%0"
  198.      : "=f" (value)
  199.      : "f" (x));
  200.   return value;
  201. }
  202.  
  203. __inline static const double
  204. tanh (double x)
  205. {
  206.   double value;
  207.  
  208.   __asm ("ftanh%.x %1,%0"
  209.      : "=f" (value)
  210.      : "f" (x));
  211.   return value;
  212. }
  213.  
  214. __inline static const double
  215. atanh (double x)
  216. {
  217.   double value;
  218.  
  219.   __asm ("fatanh%.x %1,%0"
  220.      : "=f" (value)
  221.      : "f" (x));
  222.   return value;
  223. }
  224.  
  225. __inline static const double
  226. exp (double x)
  227. {
  228.   double value;
  229.  
  230.   __asm ("fetox%.x %1,%0"
  231.      : "=f" (value)
  232.      : "f" (x));
  233.   return value;
  234. }
  235.  
  236. __inline static const double
  237. expm1 (double x)
  238. {
  239.   double value;
  240.  
  241.   __asm ("fetoxm1%.x %1,%0"
  242.      : "=f" (value)
  243.      : "f" (x));
  244.   return value;
  245. }
  246.  
  247. __inline static const double
  248. log (double x)
  249. {
  250.   double value;
  251.  
  252.   __asm ("flogn%.x %1,%0"
  253.      : "=f" (value)
  254.      : "f" (x));
  255.   return value;
  256. }
  257.  
  258. __inline static const double
  259. log1p (double x)
  260. {
  261.   double value;
  262.  
  263.   __asm ("flognp1%.x %1,%0"
  264.      : "=f" (value)
  265.      : "f" (x));
  266.   return value;
  267. }
  268.  
  269. __inline static const double
  270. log10 (double x)
  271. {
  272.   double value;
  273.  
  274.   __asm ("flog10%.x %1,%0"
  275.      : "=f" (value)
  276.      : "f" (x));
  277.   return value;
  278. }
  279.  
  280. __inline static const double
  281. sqrt (double x)
  282. {
  283.   double value;
  284.  
  285.   __asm ("fsqrt%.x %1,%0"
  286.      : "=f" (value)
  287.      : "f" (x));
  288.   return value;
  289. }
  290.  
  291. __inline static const double
  292. hypot (const double x, const double y)
  293. {
  294.   return sqrt (x*x + y*y);
  295. }
  296.  
  297. __inline static const double
  298. __pow (const double x, const double y)
  299. {
  300.   if (x > 0)
  301.     return exp (y * log (x));
  302.   else if (x == 0)
  303.     {
  304.       if (y > 0)
  305.     return 0.0;
  306.       else
  307.     {
  308.       double value;
  309.  
  310.       errno = EDOM;
  311.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  312.          : "=f" (value)
  313.          : /* no inputs */);
  314.       return value;
  315.     }
  316.     }
  317.   else
  318.     {
  319.       double temp;
  320.  
  321.       __asm ("fintrz%.x %1,%0"
  322.          : "=f" (temp)            /* integer-valued float */
  323.          : "f" (y));
  324.       if (y == temp)
  325.         {
  326.       int i = (int) y;
  327.       
  328.       if ((i & 1) == 0)            /* even */
  329.         return exp (y * log (-x));
  330.       else
  331.         return - exp (y * log (-x));
  332.         }
  333.       else
  334.         {
  335.       double value;
  336.  
  337.       errno = EDOM;
  338.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  339.          : "=f" (value)
  340.          : /* no inputs */);
  341.       return value;
  342.         }
  343.     }
  344. }
  345.  
  346. #define pow __pow
  347.  
  348. __inline static const double
  349. fabs (double x)
  350. {
  351.   double value;
  352.  
  353.   __asm ("fabs%.x %1,%0"
  354.      : "=f" (value)
  355.      : "f" (x));
  356.   return value;
  357. }
  358.  
  359. __inline static const double
  360. ceil (double x)
  361. {
  362.   int rounding_mode, round_up;
  363.   double value;
  364.  
  365.   __asm volatile ("fmove%.l %!,%0"
  366.           : "=dm" (rounding_mode)
  367.           : /* no inputs */ );
  368.   round_up = rounding_mode | 0x30;
  369.   __asm volatile ("fmove%.l %0,%!"
  370.           : /* no outputs */
  371.           : "dmi" (round_up));
  372.   __asm volatile ("fint%.x %1,%0"
  373.           : "=f" (value)
  374.           : "f" (x));
  375.   __asm volatile ("fmove%.l %0,%!"
  376.           : /* no outputs */
  377.           : "dmi" (rounding_mode));
  378.   return value;
  379. }
  380.  
  381. __inline static const double
  382. floor (double x)
  383. {
  384.   int rounding_mode, round_down;
  385.   double value;
  386.  
  387.   __asm volatile ("fmove%.l %!,%0"
  388.           : "=dm" (rounding_mode)
  389.           : /* no inputs */ );
  390.   round_down = (rounding_mode & ~0x10)
  391.         | 0x20;
  392.   __asm volatile ("fmove%.l %0,%!"
  393.           : /* no outputs */
  394.           : "dmi" (round_down));
  395.   __asm volatile ("fint%.x %1,%0"
  396.           : "=f" (value)
  397.           : "f" (x));
  398.   __asm volatile ("fmove%.l %0,%!"
  399.           : /* no outputs */
  400.           : "dmi" (rounding_mode));
  401.   return value;
  402. }
  403.  
  404. __inline static const double
  405. rint (double x)
  406. {
  407.   int rounding_mode, round_nearest;
  408.   double value;
  409.  
  410.   __asm volatile ("fmove%.l %!,%0"
  411.           : "=dm" (rounding_mode)
  412.           : /* no inputs */ );
  413.   round_nearest = rounding_mode & ~0x30;
  414.   __asm volatile ("fmove%.l %0,%!"
  415.           : /* no outputs */
  416.           : "dmi" (round_nearest));
  417.   __asm volatile ("fint%.x %1,%0"
  418.           : "=f" (value)
  419.           : "f" (x));
  420.   __asm volatile ("fmove%.l %0,%!"
  421.           : /* no outputs */
  422.           : "dmi" (rounding_mode));
  423.   return value;
  424. }
  425.  
  426. __inline static const double
  427. fmod (double x, double y)
  428. {
  429.   double value;
  430.  
  431.   __asm ("fmod%.x %2,%0"
  432.      : "=f" (value)
  433.      : "0" (x),
  434.        "f" (y));
  435.   return value;
  436. }
  437.  
  438. __inline static const double
  439. drem (double x, double y)
  440. {
  441.   double value;
  442.  
  443.   __asm ("frem%.x %2,%0"
  444.      : "=f" (value)
  445.      : "0" (x),
  446.        "f" (y));
  447.   return value;
  448. }
  449.  
  450. __inline static const double
  451. scalb (double x, int n)
  452. {
  453.   double value;
  454.  
  455.   __asm ("fscale%.l %2,%0"
  456.      : "=f" (value)
  457.      : "0" (x),
  458.        "dmi" (n));
  459.   return value;
  460. }
  461.  
  462. __inline static double
  463. logb (double x)
  464. {
  465.   double exponent;
  466.  
  467.   __asm ("fgetexp%.x %1,%0"
  468.      : "=f" (exponent)
  469.      : "f" (x));
  470.   return exponent;
  471. }
  472.  
  473. __inline static const double
  474. ldexp (double x, int n)
  475. {
  476.   double value;
  477.  
  478.   __asm ("fscale%.l %2,%0"
  479.      : "=f" (value)
  480.      : "0" (x),
  481.        "dmi" (n));
  482.   return value;
  483. }
  484.  
  485. __inline static double
  486. frexp (double x, int *exp)
  487. {
  488.   double float_exponent;
  489.   int int_exponent;
  490.   double mantissa;
  491.  
  492.   __asm ("fgetexp%.x %1,%0"
  493.      : "=f" (float_exponent)     /* integer-valued float */
  494.      : "f" (x));
  495.   int_exponent = (int) float_exponent;
  496.   __asm ("fgetman%.x %1,%0"
  497.      : "=f" (mantissa)        /* 1.0 <= mantissa < 2.0 */
  498.      : "f" (x));
  499.   if (mantissa != 0)
  500.     {
  501.       __asm ("fscale%.b %#-1,%0"
  502.          : "=f" (mantissa)        /* mantissa /= 2.0 */
  503.          : "0" (mantissa));
  504.       int_exponent += 1;
  505.     }
  506.   *exp = int_exponent;
  507.   return mantissa;
  508. }
  509.  
  510. __inline static double
  511. modf (double x, double *ip)
  512. {
  513.   double temp;
  514.  
  515.   __asm ("fintrz%.x %1,%0"
  516.      : "=f" (temp)            /* integer-valued float */
  517.      : "f" (x));
  518.   *ip = temp;
  519.   return x - temp;
  520. }
  521.  
  522. #endif /* _MATH_68881_H */
  523.